package la.iok.hzsvn.lewin.movie.service;

import la.iok.hzsvn.lewin.movie.core.exception.ErrorCode;
import la.iok.hzsvn.lewin.movie.entity.ClueCard;
import la.iok.hzsvn.lewin.movie.entity.ClueCardGroupInstance;
import la.iok.hzsvn.lewin.movie.entity.ClueCardInstance;
import la.iok.hzsvn.lewin.movie.mapper.ClueCardInstanceMapper;
import la.iok.hzsvn.lewin.movie.model.ClueCardVo;
import la.iok.hzsvn.lewin.mybatis.service.BaseServiceImpl;
import la.iok.hzsvn.share.annotations.NotNull;
import la.iok.hzsvn.share.annotations.NotNullElement;
import la.iok.hzsvn.share.annotations.Nullable;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class ClueCardInstanceServiceImpl extends BaseServiceImpl<ClueCardInstance, ClueCardInstanceMapper,Long> implements ClueCardInstanceService {
    private final ClueCardFileService clueCardFileService;
    private final ClueCardGroupInstanceService clueCardGroupInstanceService;
    public ClueCardInstanceServiceImpl(ClueCardInstanceMapper mapper,
                                       ClueCardFileService clueCardFileService,
                                       ClueCardGroupInstanceService clueCardGroupInstanceService) {
        super(mapper);
        this.clueCardFileService = clueCardFileService;
        this.clueCardGroupInstanceService = clueCardGroupInstanceService;
    }

    @NotNull
    @Override
    public Long save(@NotNull ClueCard clueCard, @NotNull Long groupInstanceId) {
        ClueCardInstance instance = new ClueCardInstance();
        BeanUtils.copyProperties(clueCard,instance);
        instance.setId(null);
        instance.setClueCardId(clueCard.getId());
        instance.setGroupInstanceId(groupInstanceId);
        insertSelective(instance);
        clueCardFileService.increment(instance.getHdFileId());
        clueCardFileService.increment(instance.getSdFileId());
        return instance.getId();
    }

    @NotNull
    @NotNullElement
    @Override
    public List<ClueCardVo> clueCards(Collection<Long> groupInstanceIds) {
        List<ClueCardInstance> list = listInProperty("groupInstanceId",groupInstanceIds);
        return list.stream().map(this::po2vo).collect(Collectors.toList());
    }

    @Override
    public List<ClueCardVo> clueCards(Long movieInstanceId) {
        List<ClueCardGroupInstance> list = clueCardGroupInstanceService.listByProperty("movieInstanceId",movieInstanceId);
        Collection<Long> groupIds = list.stream().map(ClueCardGroupInstance::getId).collect(Collectors.toSet());
        return clueCards(groupIds);
    }

    @Nullable
    @Override
    public String hdFileDigest(@Nullable Long movieInstanceId, @Nullable Long id) {
        ClueCardInstance cardInstance = getClueCardInstance(movieInstanceId, id);
        if(cardInstance == null){
            return null;
        }
        return clueCardFileService.digest(cardInstance.getHdFileId());
    }

    @Nullable
    @Override
    public String hdFileStorePath(@Nullable Long movieInstanceId, @Nullable Long id) {
        ClueCardInstance cardInstance = getClueCardInstance(movieInstanceId, id);
        if(cardInstance == null){
            return null;
        }
        return clueCardFileService.storePath(cardInstance.getHdFileId());
    }

    @Override
    public String sdFileDigest(Long movieInstanceId, Long clueCardId) {
        ClueCardInstance cardInstance = getClueCardInstance(movieInstanceId, clueCardId);
        if(cardInstance == null){
            return null;
        }
        return clueCardFileService.digest(cardInstance.getSdFileId());
    }

    @Override
    public String sdFileStorePath(Long movieInstanceId, Long clueCardId) {
        ClueCardInstance cardInstance = getClueCardInstance(movieInstanceId, clueCardId);
        if(cardInstance == null){
            return null;
        }
        return clueCardFileService.storePath(cardInstance.getSdFileId());
    }

    @Override
    public void downloadSdFile(@NotNull HttpServletResponse response, @Nullable Long movieInstanceId, @Nullable Long clueCardId) {
        ClueCardInstance cardInstance = getClueCardInstance(movieInstanceId, clueCardId);
        ErrorCode.CLUE_CARD_NOT_EXIST.assertNotNull(cardInstance,clueCardId);
        clueCardFileService.downloadFile(response,cardInstance.getSdFileId(), cardInstance.getName());
    }

    @Override
    public void downloadHdFile(HttpServletResponse response, Long movieInstanceId, Long clueCardId) {
        ClueCardInstance cardInstance = getClueCardInstance(movieInstanceId, clueCardId);
        ErrorCode.CLUE_CARD_NOT_EXIST.assertNotNull(cardInstance,clueCardId);
        clueCardFileService.downloadFile(response,cardInstance.getHdFileId(), cardInstance.getName());
    }

    @Override
    public void markFileDeleted(Collection<Long> ids) {
        batchUpdate("fileDeleted",1,ids);
    }

    private ClueCardInstance getClueCardInstance(@Nullable Long movieInstanceId, @Nullable Long clueCardId) {
        List<ClueCardGroupInstance> list = clueCardGroupInstanceService.listByProperty("movieInstanceId",movieInstanceId);
        Collection<Long> groupIds = list.stream().map(ClueCardGroupInstance::getId).collect(Collectors.toSet());
        List<ClueCardInstance> records = listInProperty("groupInstanceId",groupIds);
        return records.stream().filter(item-> Objects.equals(clueCardId,item.getClueCardId())).findFirst().orElse(null);
    }

    private ClueCardVo po2vo(ClueCardInstance po){
        ClueCardVo vo = new ClueCardVo();
        BeanUtils.copyProperties(po,vo);
        vo.setId(po.getClueCardId());
        vo.setGroup(po.getGroupId());
        return vo;
    }
}
